package com.syf.kit.core.dao.sql.parse;

import java.util.Map;

/**
 * 静态转换，例如将  sql:  select * from ${table}  转换为 select * from tableName1;
 */
public class ReplaceHolderConverter {
    /**
     * 转换开始标志
     */
    private final String openToken;

    /**
     * 转换结束标志
     */
    private final String closeToken;

    public ReplaceHolderConverter(String openToken, String closeToken) {
        this.openToken = openToken;
        this.closeToken = closeToken;
    }

    public String parse(String sql, Map<String, Object> paramMap) {
        StringBuilder builder = new StringBuilder();
        StringBuilder expression = new StringBuilder();
        if (sql != null && sql.length() > 0) {
            char[] src = sql.toCharArray();
            int offset = 0;
            int start = sql.indexOf(this.openToken, offset);
            while (start > -1) {
                if (start > 0 && src[start - 1] == '\\') {
                    builder.append(src, offset, start - offset - 1).append(this.openToken);
                    offset = start + this.openToken.length();
                } else {
                    expression.setLength(0);
                    builder.append(src, offset, start - offset);
                    offset = start + this.openToken.length();
                    int end = sql.indexOf(this.closeToken, offset);
                    while (end > -1) {
                        if (end > offset && src[end - 1] == '\\') {
                            expression.append(src, offset, end - offset - 1).append(this.closeToken);
                            offset = end + this.closeToken.length();
                            end = sql.indexOf(this.closeToken, offset);
                            continue;
                        }
                        expression.append(src, offset, end - offset);
                        offset = end + this.closeToken.length();
                        break;
                    }
                    if (end == -1) {
                        builder.append(src, start, src.length - start);
                        offset = src.length;
                    } else {
                        builder.append(paramMap.get(expression.toString()));
                        offset = end + this.closeToken.length();
                    }
                }
                start = sql.indexOf(this.openToken, offset);
            }
            if (offset < src.length)
                builder.append(src, offset, src.length - offset);
        }
        return builder.toString();
    }
}
